/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package technotheist.geo.mesh;

import com.jme3.math.Vector2f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.control.LodControl;
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import static technotheist.geo.mesh.PatchUtil.*;

/**
 *
 * @author Mitchel Strachan
 */
public class PlanetPatch extends Geometry {

    /*
     * 
     * 
     * 
     * 
     */
    final byte panel;
    private final Vector2f offset;
    final float extent, step;
    private byte detail = PatchUtil.MIN_DETAIL;
    protected int lodID = 0;
    PlanetPatch nw, sw, se, ne;
//    final FloatBuffer pos, nor, col;
    private final PlanetGeom planet;

    PlanetPatch(PlanetGeom planet, byte panel, float offsetU, float offsetV, float extent) {
        this.planet = planet;
        this.panel = panel;
        this.offset = new Vector2f(offsetU, offsetV);
        this.extent = extent;
        this.step = extent / SIDE_QUADS;
        this.mesh = new Mesh();
        this.mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(AREA_VERTS * 3));
        this.mesh.setBuffer(VertexBuffer.Type.Normal, 3, BufferUtils.createFloatBuffer(AREA_VERTS * 3));
        this.mesh.setBuffer(VertexBuffer.Type.Color, 3, BufferUtils.createFloatBuffer(AREA_VERTS * 4));
        this.mesh.setBuffer(VertexBuffer.Type.TexCoord, 2, CreateUV(offset, step));        this.mesh.setBuffer(PatchUV);//TexCoord2

    }

    protected FloatBuffer posBuffer() {
        return mesh.getFloatBuffer(VertexBuffer.Type.Position);
    }

    protected FloatBuffer norBuffer() {
        return mesh.getFloatBuffer(VertexBuffer.Type.Normal);
    }

    protected FloatBuffer colBuffer() {
        return mesh.getFloatBuffer(VertexBuffer.Type.Color);
    }

    private static FloatBuffer CreateUV(Vector2f offset, float step) {
        FloatBuffer uv = BufferUtils.createFloatBuffer(AREA_VERTS * 2);

        for (int u = 0; u < SIDE_VERTS; u++) {
            for (int v = 0; v < SIDE_VERTS; v++) {
                int i = 2 * (u + v * SIDE_VERTS);
                uv.put(i, offset.x + u * step);
                uv.put(i + 1, offset.y + v * step);
            }
        }
        return uv;
    }

    public static class PlanetPatchLODController extends LodControl {

        static int lodID(byte thisDetail, byte nw, byte sw, byte se, byte ne) {
            if (thisDetail == PatchUtil.MIN_DETAIL) {
                return 0;
            } else {
                boolean nwFull = nw >= thisDetail;
                boolean swFull = sw >= thisDetail;
                boolean seFull = se >= thisDetail;
                boolean neFull = ne >= thisDetail;
                return 1 + (thisDetail - PatchUtil.MIN_DETAIL) * PatchUtil.SIZE + PatchUtil.LevelID(nwFull, swFull, seFull, neFull);
            }
        }
        PlanetPatch patch;
    }
}
